---
--类名: HistoryManager.lua
--创建日期: 2018-4-23
--创建人: 宋建邦
--功能描述: 
--修改内容:
--修改日期:   
--修改人:      
--修改备注: 
--

local HistoryManager = class("HistoryManager")
local Crontab = require("app.utils.Crontab")

local table_insert = table.insert
local table_sort = table.sort
local string_split = string.split

function HistoryManager:ctor()
    self.ages = {}
    self.hages = {}
    self.events = {}
    self.hevents = {}
    self.age2events = {}
    self.age2pages = {}
    self.serverages = {}
    self.server_kind2events = {}
    self.server_age2events = {}
    self.serverevents = {}
    self.newspaperDateByPage = {} -- 报纸每一页对应的是哪一年哪一月
    self.newspaperCalendar = {} -- 报纸日历详细信息
    self.newspaperInfo = {} -- 某天单张报纸的详细信息

    self:initPages()

    -- self:requestEvents(1)
    -- self:requestEvents(2)
    -- self:requestEvents(3)
    -- self:requestEvents(4)
end

function HistoryManager:requestEvents(aKind)
    app.session:request("pb_gloryhistory.C2S_GloryHistoryList", {kind=aKind}, function(msg)
        if msg.age and #msg.age > 0 then
            self.serverages = {}
            for _, v in ipairs(msg.age) do
                v.ID = v.age
                table.insert(self.serverages, v)
            end
            table.sort(self.serverages, function(a, b)
                if a.startTime == b.startTime then
                    return a.age < b.age
                else
                    return a.startTime < b.startTime
                end
            end)
        end

        self.server_kind2events[aKind] = {}
        for _, v in ipairs(msg.events) do
            if self.hevents[v.id] then
                setmetatable(v, {__index=self.hevents[v.id]})
            end
            table.insert(self.server_kind2events[aKind], v)
        end

        self.serverevents = {}
        for k, v in pairs(self.server_kind2events) do 
            for _, e in ipairs(v) do 
                if self.hevents[e.id] then
                    local le = clone(self.hevents[e.id])
                    table.merge(le, e)
                    
                    table.insert(self.serverevents, le)
                end
            end            
        end 

        table.sort(self.serverevents, function (a, b) 
            if a.finishTime == b.finishTime then
                if checknumber(a.finishStamp) ~= 0 and checknumber(b.finishStamp) ~= 0 then
                    if checknumber(a.finishStamp) == checknumber(b.finishStamp) then
                        return checknumber(a.orderNum) < checknumber(b.orderNum)
                    else
                        return checknumber(a.finishStamp) < checknumber(b.finishStamp)
                    end                    
                else
                    return checknumber(a.orderNum) < checknumber(b.orderNum)
                end
            else
                return a.finishTime < b.finishTime
            end
        end)

        self.server_age2events = {}
        for i, v in ipairs(self.serverevents) do 
            local a = self:getAgeByEventTime(v.finishTime)
            if a ~= nil then
                local evts = self.server_age2events[a.age] or {}

                -- table.merge(v, self.hevents[v.id])
                table.insert(evts, v)

                self.server_age2events[a.age] = evts
            end
        end

        for k, v in pairs(self.server_age2events) do
            self:layoutPage(k, v)
        end

        -- dump(self.server_age2events)
        app:dispatchCustomEvent("HISTORY_DATA_CHANGE_EVENT",{msg=msg})

    end, nil, function(errMsg)
    end)
end

function HistoryManager:layoutPage(aAgeID, aEvents)
    local pages = {}
    local curH = 5
    local function t2h(t)
        if t == 3 then
            return 4
        else
            return t
        end
    end
    for _, e in ipairs(aEvents) do
        if t2h(e.type) + curH > 4 then
            pages[#pages + 1] = {ageID = aAgeID}
            curH = 0                
        end
        table.insert(pages[#pages], e)

        curH = curH + t2h(e.type)
    end

    self.age2pages[aAgeID] = pages
end

function HistoryManager:initPages()
    local ages = GD:getHistoryAges()
	local events = GD:getHistoryEvents()

	for _, v in ipairs(ages) do 
        local tv = v:getValues()
        tv.ID = tonumber(tv.ID)
        tv.startCondition = tonumber(tv.startCondition)
        if tv.startCondition == 0 then
            table.insert(self.ages, tv)
        end
        self.hages[tv.ID] = tv
    end
    table.sort(self.ages, function(a, b) return a.ID < b.ID end )

	for _, v in ipairs(events) do 
        local tv = v:getValues()
        tv.ID = tonumber(tv.ID)
        tv.belongToAge = tonumber(tv.belongToAge)
        tv.type = tonumber(tv.type)
        tv.kind = tonumber(tv.kind)
        table.insert(self.events, tv)
        tv.getGuildInfo = function(self)
            if self.kvStore then
                local ret = {}
                for i, v in ipairs(self.kvStore) do
                    if string.find(v.key, "_guildFlagInfo") then
                        local parts = string.split(v.val, "|")
                        table.insert(ret, {
                            guildName = string.sub(v.key, 1, v.key:find("_guildFlagInfo")),
                            FlagBaseIcon = parts[1],
                            FlagBaseIconColor = checknumber(parts[2]),
                            FlagAdditionalIcon = parts[3],
                            FlagAdditionalIconColor = checknumber(parts[4])
                        })
                    end
                end
                if #ret > 0 then
                    return ret
                else
                    return nil
                end
            end

            return nil
        end
        self.hevents[tv.ID] = tv  

        local evts = self.age2events[tv.belongToAge] or {}
        table.insert(evts, tv)

        self.age2events[tv.belongToAge] = evts
    end 
    
    table.sort(self.events, function(a, b) return tonumber(a.ID) < b.ID end)
    for k, v in pairs(self.age2events) do
        table.sort(v, function(a, b) return a.ID < b.ID end )
        self:layoutPage(k, v)
    end
end

function HistoryManager:refreshServerPages()
end

function HistoryManager:getAgeByID(aId)
    -- for _, v in ipairs(self.ages) do
    --     if v.ID == aId then
    --         return v 
    --     end
    -- end
    return self.hages[aId]
end

function HistoryManager:getPageCount()
    local ret = 0
    
    for _,v in ipairs(self.ages) do
        ret = ret + #self.age2pages[v.ID]
    end
    for _,v in ipairs(self.serverages) do
        if self.age2pages[v.ID] then
            ret = ret + #self.age2pages[v.ID]
        end
    end

    return ret 
end

function HistoryManager:getPage(aPageIndex)
    -- if math.fmod(aPageIndex, 2) ~= 0 then
    --     aPageIndex = math.max(aPageIndex - 1, 1)
    -- end
    aPageIndex = math.max(aPageIndex, 1)

    local ret = {}
    local curIndex = 0
    local allages = {}
    for _,v in ipairs(self.ages) do
        table.insert(allages, v)
    end
    for _,v in ipairs(self.serverages) do
        table.insert(allages, v)
    end
    for i, a in ipairs(allages) do
        if self.age2pages[a.ID] then
            if #self.age2pages[a.ID] + curIndex >= aPageIndex then
                ret[1] = self.age2pages[a.ID][aPageIndex - curIndex]
                if self.age2pages[a.ID][aPageIndex - curIndex + 1] then
                    ret[2] = self.age2pages[a.ID][aPageIndex - curIndex + 1]
                    return ret
                else 
                    local index = i + 1
                    while(allages[index])
                    do
                        if self.age2pages[allages[index].ID] and self.age2pages[allages[index].ID][1] then
                            ret[2] = self.age2pages[allages[index].ID][1]

                            return ret 
                        end
                        index = index + 1
                    end
                end
            else
                curIndex = curIndex + #self.age2pages[a.ID]
            end
        end
    end

    return ret
end

function HistoryManager:getAgeByEventTime(t)
    for _, a in ipairs(self.serverages) do 
        if a.endTime and t < a.endTime then
            return a
        end
    end

    return self.serverages[#self.serverages]
end

function HistoryManager:refreshFootPrintPage()
    local evts = self.server_kind2events[4] or {}--足迹事件
    table.sort(evts, function(a, b )
        if a.finishTime == b.finishTime then
            if a.finishStamp ~= b.finishStamp then
                return a.finishStamp < b.finishStamp
            else
                return checknumber(a.orderNum) < checknumber(b.orderNum)
            end
        else
            return a.finishTime < b.finishTime
        end
    end)

    self.footprint_timemap = {h={}, a={}}
    for _, v in ipairs(evts) do
        local k = math.floor(v.finishTime/100)
        if self.footprint_timemap.h[k] then
            table.insert(self.footprint_timemap.h[k], v)
        else
            self.footprint_timemap.h[k] = {v}
            table.insert(self.footprint_timemap.a, k)
        end
    end

    -- for _, v in ipairs(self.footprint_timemap.a) do
    --     v.lineCount = math.ceil(#v / 3)
    -- end

end

function HistoryManager:getFootPrintPageCount()
    local pc = 0
    local lc = 0
    for i, v in ipairs(self.footprint_timemap.a) do
        local tv = self.footprint_timemap.h[v]
        lc = lc + math.ceil(#tv / 3)
    end

    return math.ceil((lc + 1)/5)
end

function HistoryManager:getFootPrintPage(aPageIndex)
    self:refreshFootPrintPage()
    local lineIndex = (aPageIndex - 1) * 5

    if lineIndex > 1 then
        lineIndex = lineIndex - 1
    end

    self.minTime = 99990909
    self.maxTime = 0

    local curIndex = 0
    local lines = {}
    if aPageIndex == 1 then
        table.insert(lines, {firstline=true})
    end
    local function checktime(atv)
        if not atv then
            return 
        end
        local ft = checknumber(atv.finishTime)
        -- dump(atv)
        --print("time....."..tostring(atv.finishTime))
        if ft > 0 then
            if ft > self.maxTime then
                self.maxTime = ft
            end
            if ft < self.minTime then
                self.minTime = ft
            end
        end
    end

    for i, v in ipairs(self.footprint_timemap.a) do
        local tv = self.footprint_timemap.h[v]
        
        if curIndex + math.ceil(#tv / 3) >= lineIndex then
            local sindex = (lineIndex - curIndex)*3 + 1
            while(tv and tv[sindex] and #lines < 11)
            do 
                local l = {tv[sindex], tv[sindex+1], tv[sindex+2]}
                checktime(tv[sindex])
                checktime(tv[sindex + 1])
                checktime(tv[sindex + 2])
                l.isfirst = sindex == 1
                lines[#lines + 1] = l
                if not tv[sindex+3] then
                    tv = self.footprint_timemap.h[self.footprint_timemap.a[i + 1]]
                    i = i + 1
                    sindex = 1
                else
                    sindex = sindex + 3
                end
            end
            break
        else
            curIndex = curIndex + math.ceil(#tv / 3)
        end
    end

    -- print("**********************************", aPageIndex)
    -- dump(lines)

    return lines
end

function HistoryManager:transTime(t)
    local ret = {}
    ret.y = math.floor(t/10000)
    ret.m = math.floor(math.fmod(t, 10000) / 100)
    ret.d = math.fmod(t, 100)
    return ret 
end

function HistoryManager:getGameTime()
    if #self.footprint_timemap.a <= 0 then
        return 0, 1
    end
    local mn = self:transTime(self.minTime)
    local mx = self:transTime(self.maxTime)

    local y = mx.y - mn.y 
    local m = mx.m - mn.m 

    local ms = y * 12 + m + 1
    
    y = math.floor(ms/12)
    m = math.fmod(ms, 12)

    return y , m
end

function HistoryManager:initEvents()
    if self.inited then
        return
    end
    self.inited = true
    -- app:sendMsg("IMRoomController", "enterWords", "/historyGm event 400090 1")
    -- app:getInst("IMRoomController"):enterWords("/historyGm event 400090 1")
end

function HistoryManager:transDesc(fstr, params, t)
    if t then
        fstr = string.gsub(fstr, "%%t", tostring(t))
    end    

    if not params or #params <= 0 then
        return fstr
    end
    
    for i = 1, #params do
        fstr = string.gsub(fstr, "%%s"..i, L(params[i]))
    end
    return fstr
end

------------------------------------------------------------------
---报纸系统
------------------------------------------------------------------
-- 初始化日历结构(key=pageIndex, value={year=2019, month=3, maxday=31})
function HistoryManager:initNewsPaper()
    self.newspaperDateByPage = {}
    local openDate = app.session:getOpenServerDate() -- 开服时间
    local curDate = app.session:getServerDate() -- 当前时间
    local pageCount = self:getNewsPaperCount()
    local newDate = {year = openDate.year, month = openDate.month, maxday = Crontab:getDayMaxPreMonth(openDate.year, openDate.month)}
    for i = 1, pageCount do
        table_insert(self.newspaperDateByPage, clone(newDate))
        if newDate.year < curDate.year then
            if newDate.month < 12 then
                newDate.month = newDate.month + 1
            else
                newDate.year = newDate.year + 1
                newDate.month = 1
            end
        else
            if newDate.month < curDate.month then
                newDate.month = newDate.month + 1
            else
                break
            end
        end
        newDate.maxday = Crontab:getDayMaxPreMonth(newDate.year, newDate.month)
    end
    -- dump(self.newspaperDateByPage, "initNewsPaper")
end

-- 获取无尽日报日历
function HistoryManager:reqGetNewspaperCalendar(pageIndex)
    local leftPageIndex, rightPageIndex
    if not pageIndex then
        if self:getNewsPaperCount() % 2 ~= 0 then
            leftPageIndex = self:getNewsPaperCount()
            rightPageIndex = leftPageIndex
        else
            leftPageIndex = self:getNewsPaperCount() - 1
            rightPageIndex = leftPageIndex + 1
        end
    else
        leftPageIndex = pageIndex
        rightPageIndex = math.min(pageIndex + 1, self:getNewsPaperCount())
    end
    -- print("leftPageIndex-------->>>>", leftPageIndex)
    -- print("rightPageIndex-------->>>>", rightPageIndex)
    if not self.newspaperCalendar[leftPageIndex] or not self.newspaperCalendar[rightPageIndex] then
        self.newspaperCalendar[leftPageIndex] = clone(self.newspaperDateByPage[leftPageIndex])
        self.newspaperCalendar[rightPageIndex] = clone(self.newspaperDateByPage[rightPageIndex])
        local startDateInfo = self.newspaperCalendar[leftPageIndex]
        local endDateInfo = self.newspaperCalendar[rightPageIndex]
        local startDateStr = string.format("%s/%s/%s", startDateInfo.year, startDateInfo.month, 1)
        local endDateStr = string.format("%s/%s/%s", endDateInfo.year, endDateInfo.month, endDateInfo.maxday)
        app.session:request("pb_newspaper.C2S_GetNewspaperCalendar", {StartDate = startDateStr, EndDate = endDateStr}, function(msg)
            -- dump(msg, "S2C_GetNewspaperCalendar")
            startDateInfo.info = {}
            endDateInfo.info = {}
            for i, v in ipairs(msg.Info) do
                local dateInfo = string_split(v.Date, "/")
                if tonumber(dateInfo[1]) == startDateInfo.year and tonumber(dateInfo[2]) == startDateInfo.month then
                    startDateInfo.info[tonumber(dateInfo[3])] = v.Type   
                elseif tonumber(dateInfo[1]) == endDateInfo.year and tonumber(dateInfo[2]) == endDateInfo.month then
                    endDateInfo.info[tonumber(dateInfo[3])] = v.Type 
                end 
            end
            app:dispatchCustomEvent("NEWSPAPER_CALENDAR_CHANGE_EVENT", {pageIndex = leftPageIndex})
        end)
    else
        app:dispatchCustomEvent("NEWSPAPER_CALENDAR_CHANGE_EVENT", {pageIndex = leftPageIndex})
    end      
end

-- 报纸总页数(当前时间到开服时间之间月数差)
function HistoryManager:getNewsPaperCount()
    local count = 0
    local openDate = app.session:getOpenServerDate() -- 开服时间
    local curDate = app.session:getServerDate() -- 当前时间
    if curDate.year ~= openDate.year then
        count = (12 - openDate.month) + (curDate.year - openDate.year - 1)*12 + curDate.month
    else
        count = curDate.month - openDate.month + 1
    end
    return count
end

function HistoryManager:getNewsPaperCalendarPage(pageIndex)
    local ret = {}
    if self.newspaperCalendar[pageIndex] then
        ret[1] = self.newspaperCalendar[pageIndex]
    end
    if self.newspaperCalendar[pageIndex+1] then
        ret[2] = self.newspaperCalendar[pageIndex+1]
    end
    return ret
end

local function v_sortNews(a, b)
    local tensDigitA = math.floor(a.formatType / 10)
    local unitsDigitA = a.formatType % 10
    local AreaSizeA = tensDigitA*unitsDigitA
    local tensDigitB = math.floor(b.formatType / 10)
    local unitsDigitB = b.formatType % 10
    local AreaSizeB = tensDigitB*unitsDigitB
    if AreaSizeA ~= AreaSizeB then
        return AreaSizeA > AreaSizeB
    else
        return a.pos < b.pos
    end
end

-- 获取当天单张报纸详细信息
function HistoryManager:reqGetNewspaperInfo(dateStr)
    -- print("reqGetNewspaperInfo.dateStr------->>>>", dateStr)
    if not self.newspaperInfo[dateStr] then
        app.session:request("pb_newspaper.C2S_GetNewspaperInfo", {Date = dateStr}, function(msg)
            -- dump(msg, "S2C_GetNewspaperInfo")
            if msg.Info then
                local newsList = msg.Info.News
                local frontPageConf = GD:getNewsPaperFormatById(msg.Info.FrontPageTyp)
                local secondPageConf = GD:getNewsPaperFormatById(msg.Info.SecondPageTyp)
                if frontPageConf and secondPageConf then
                    -- 样式按照面积从大到小，位置从小到大排序
                    local formatList = {} 
                    local frontFormatList = string.splitTwice(frontPageConf.formatPosition, {";", "|"}, true)
                    local secondFormatList = string.splitTwice(secondPageConf.formatPosition, {";", "|"}, true)
                    for i, v in ipairs(frontFormatList) do
                        table_insert(formatList, {formatType = v[1], pos = v[2]})
                    end 
                    for i, v in ipairs(secondFormatList) do
                        table_insert(formatList, {formatType = v[1], pos = v[2]})
                    end 
                    table_sort(formatList, v_sortNews)
                    
                    -- map={[33]={num = 2, leftnum = 1, index = {1, 3}} }
                    -- 33:格子样式id，num:有几个33的格子，leftnum:被占用的格子数，index:33格子所对应的table索引
                    local formatMap = {}
                    for i, v in ipairs(formatList) do
                        local fm = formatMap[v.formatType]
                        if not fm then
                            fm = {num = 0, leftnum = 0, index={}}
                        end
                        fm.num = fm.num + 1
                        fm.index[#fm.index+1] = i
                    end

                    local newsList2 = {}
                    for k, v in ipairs(newsList) do
                        local eventId = v.ID
                        local conf = GD:getNewsPaperEventById(eventId)
                        if conf and conf.firstPcik then
                            local info = formatMap[tonumber(conf.firstPcik)]
                            if info and info.num - info.leftnum > 0 then
                                local index = info.index[info.leftnum+1]
                                formatList[index].eventId = eventId
                                formatList[index].newsInfo = v.PlayerInfo
                            else
                                table.insert(newsList2, v)
                            end
                        else
                            table.insert(newsList2, v)
                        end
                    end              
                    local idx = 1
                    for i, v in ipairs(formatList) do
                        local t = newsList2[idx]
                        if not v.eventId and t then
                            v.eventId = t.ID
                            v.newsInfo = t.PlayerInfo
                        end
                        idx = idx + 1
                    end

                    self.newspaperInfo[dateStr] = {date = dateStr, issue = msg.Info.IssueNum, info = formatList}
                    app:sendMsg("NewsPaperController", "openView", self.newspaperInfo[dateStr])
                end
            end
        end)
    else
        app:sendMsg("NewsPaperController", "openView", self.newspaperInfo[dateStr])
    end
end

-- 清除指定日期当月的日历缓存数据,并在主界面右下角显示一个提示
function HistoryManager:parseNewspaperNotify(date)
    if not date then return end
    local dateList = string_split(date, "/")
    for i, v in ipairs(self.newspaperCalendar) do
        if tonumber(dateList[1]) == v.year and tonumber(dateList[2]) == v.month then
            self.newspaperCalendar[i] = nil
            break
        end
    end
    self._showTipsDate = date
    if UIHandler:getDesktopModel() then
        self:showNewsPaperTips()
    end
end

function HistoryManager:showNewsPaperTips()
    if self._showTipsDate then
        if UIHandler:isFunctionOpen(Constant.FUNC_TYPE_NEWSPAPER) and 
            not UD:isFeatureClosedByServer(Constant.FUNC_TYPE_NEWSPAPER) then --开启报纸且服务器没有动态关闭
            local params = {
                remindId = Constant.FUNC_TYPE_NEWSPAPER,
                dataTemp = self._showTipsDate,
            }
            local desktopController = UIHandler:getDesktopController()
            if desktopController then
                desktopController:insertFourthTips( params )
            end
        end
        self._showTipsDate = nil
    end
end

return HistoryManager